package interfaces;

import java.awt.Color;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.swing.JPanel;

import model.UserDataWrapper;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickMarkPosition;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.axis.DateTickUnitType;
import org.jfree.chart.axis.TickUnits;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Day;
import org.jfree.data.time.Minute;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.joda.time.DateTime;

public class SleepChart extends JPanel {
	private static final long serialVersionUID = 1L;
	private final JFreeChart chart;
	private final SimpleDateFormat formatter = new SimpleDateFormat("HH:mm");;
	public SleepChart(List<UserDataWrapper> data) {
		super();

        chart = createChart(getDataSetFromData(data));
        final ChartPanel chartPanel = new ChartPanel(chart);
        add(chartPanel);
	}
	public SleepChart() {
		super();

        chart = createChart(new TimeSeriesCollection());
        final ChartPanel chartPanel = new ChartPanel(chart);
        add(chartPanel);
	}
	private XYDataset getDataSetFromData(List<UserDataWrapper> data) {
		TimeSeries morningSeries = convertToMorningSeries(data);
		TimeSeries eveningSeries = convertToEveningSeries(data);
	    TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(morningSeries);
        dataset.addSeries(eveningSeries);
        return dataset;
	}
	   private Long dateTimeToTime(DateTime time) {
	        int minuteOfHour = time.getMinuteOfHour();
			int hourOfDay = time.getHourOfDay();
			System.out.println(hourOfDay + ":" + minuteOfHour);
			final Minute m = new Minute(minuteOfHour, hourOfDay, 1, 1, 1970);
	        return new Long(m.getFirstMillisecond());
	    }
	private TimeSeries convertToEveningSeries(List<UserDataWrapper> data) {
		TimeSeries series = new TimeSeries("Лёг спать");
		for(UserDataWrapper udw : data) {
			series.add(new Day(udw.getDate().toDate()), dateTimeToTime(udw.getEndTime()));
		}
		return series;
	}

	private TimeSeries convertToMorningSeries(List<UserDataWrapper> data) {
		TimeSeries series = new TimeSeries("Проснулся");
		for(UserDataWrapper udw : data) {
			series.add(new Day(udw.getDate().toDate()), dateTimeToTime(udw.getStartTime()));
		}
		return series;
	}

	
	 /**
     * Creates a chart.
     * 
     * @param dataset  the dataset.
     * 
     * @return The chart.
     */
    private JFreeChart createChart(final XYDataset dataset) {
        final JFreeChart chart = ChartFactory.createTimeSeriesChart(
            "Менеджмент времени",
            "Дата", 
            "Время",
            dataset,
            true,  // legend
            true,  // tool tips
            false  // URLs
        );
        final XYPlot plot  = chart.getXYPlot();
        chart.setBackgroundPaint(Color.white);
        DateAxis myHorizontalAxis = (DateAxis) plot.getDomainAxis(); 
        myHorizontalAxis.setAutoTickUnitSelection(false); 
        final TickUnits standardUnits = new TickUnits();
        standardUnits.add(
            new DateTickUnit(DateTickUnitType.DAY, 1, new SimpleDateFormat("MM/dd/yyyy"))
        );
        standardUnits.add(
                new DateTickUnit(DateTickUnitType.DAY, 7, new SimpleDateFormat("MM/dd/yyyy"))
        );
        standardUnits.add(
                new DateTickUnit(DateTickUnitType.MONTH, 1, new SimpleDateFormat("MM/yyyy"))
        );
        final XYItemRenderer renderer = plot.getRenderer();
        if (renderer instanceof XYLineAndShapeRenderer) {
        	System.out.println("lol");
            XYLineAndShapeRenderer rr = (XYLineAndShapeRenderer) renderer;
            rr.setBaseShapesVisible(true);
            rr.setBaseShapesFilled(true);
            rr.setUseFillPaint(true);
            rr.setSeriesToolTipGenerator(0, new StandardXYToolTipGenerator() {
                private static final long serialVersionUID = 1L;
                public String generateToolTip(XYDataset dataset, int series, int item) {
                	Long y = (Long) dataset.getY(series, item);
                    return "Проснулся в " + new SimpleDateFormat("HH:mm").format(new Date(y));
                }
             });
            rr.setSeriesToolTipGenerator(1, new StandardXYToolTipGenerator() {
                private static final long serialVersionUID = 1L;
                public String generateToolTip(XYDataset dataset, int series, int item) {
                	Long y = (Long) dataset.getY(series, item);
                    return "Лёг спать в " + new SimpleDateFormat("HH:mm").format(new Date(y));
                }
             });
        }
        myHorizontalAxis.setStandardTickUnits(standardUnits); 
        myHorizontalAxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE);
        plot.setDomainAxis(myHorizontalAxis);
        
        final DateAxis myVerticalAxis = new DateAxis("Время");
        myVerticalAxis.setLowerMargin(0.15);
        myVerticalAxis.setUpperMargin(0.15);
        myVerticalAxis.setAutoTickUnitSelection(false); 
		myVerticalAxis.setTickUnit(new DateTickUnit(DateTickUnitType.HOUR, 2, formatter)); 
        myVerticalAxis.setAutoRange(false);
        myVerticalAxis.setRange(new Minute(0, 0, 1, 1, 1970).getStart(), new Minute(0, 24, 1, 1, 1970).getEnd());
        plot.setRangeAxis(myVerticalAxis);
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);
        
        return chart;      
    }
    public void setData(List<UserDataWrapper> data) {
    	chart.getXYPlot().setDataset(getDataSetFromData(data));
    }
    
}
